package com.xzm.factory;

import com.xzm.domain.Account;
import com.xzm.service.IAccountService;
import com.xzm.utils.TransactionManager;

import javax.print.event.PrintJobAttributeEvent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 3052
 * @create 2020-07-29 19:01
 */
public class BeanFactory {

    private  IAccountService accountService;
    private TransactionManager txManager;

    /**
     *         获取Service的代理对象
     * @return
     */
    public IAccountService getAccountService() {
        //目标对象，即被代理对象，在这里就是iAccountService
        IAccountService iAccountService = (IAccountService) Proxy.newProxyInstance(accountService.getClass().getClassLoader(), accountService.getClass().getInterfaces(), new InvocationHandler() {
            /**
             *      添加事务的支持
             * @param proxy
             * @param method
             * @param args
             * @return
             * @throws Throwable
             */
            //invoke方法称为环绕通知，环绕通知有明确的切入点方法调用
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                try {
                    Object rtValue = null;
                    //对test方法不拦截
                    if(method.getName().equals("test")){
                       return  method.invoke(accountService, args);
                    }
                    txManager.beginTransaction();//前置通知
                    rtValue = method.invoke(accountService, args);
                    txManager.commit();//后置通知
                    return rtValue;
                } catch (Exception e) {
                    txManager.rollback();//异常通知
                    e.printStackTrace();
                } finally {
                    txManager.release();
                }
                return null;
            }
        });
        return iAccountService;
    }

    public void setAccountService(IAccountService accountService) {
        this.accountService = accountService;
    }

    public void setTxManager(TransactionManager txManager) {
        this.txManager = txManager;
    }
}
